package com.blue.firecat.init;

import com.blue.firecat.contants.Contants;
import com.blue.firecat.contants.Result;
import com.blue.firecat.dto.TradeStatusDto;
import com.blue.firecat.entity.Game;
import com.blue.firecat.entity.OrderExample;
import com.blue.firecat.enums.OrderTypeEnum;
import com.blue.firecat.enums.TradeStatusEnum;
import com.blue.firecat.serivce.GameService;
import com.blue.firecat.serivce.OrderService;
import com.blue.firecat.serivce.TradeService;
import com.blue.firecat.utils.data.MySQLDatabaseBackup;
import com.blue.firecat.utils.date.DateUtil;
import com.blue.firecat.utils.property.PropertiesUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static com.blue.firecat.contants.Contants.TRADE_STATUS_RESULT;

/**
 * @描述 初始化方法 做一个定时任务
 * @时间 2017-6-23 18:27
 * @作者 肖亦鸣
 */
public class Init {
    private static Logger logger = LogManager.getLogger(Init.class.getName());

    @Autowired
    OrderService orderService;
    @Autowired
    GameService gameService;
    @Autowired
    TradeService tradeService;

    private static final ScheduledExecutorService service = Executors.newScheduledThreadPool(5);

    public Init() {
        logger.info("Timed tasks Init start...{}", DateUtil.getCurrentDate());
        this.initTradeStatus();
    //    this.initScheduledExecutorService();
        this.initScheduledGameCount();
        this.initScheduledExpired();
        //    this.initScheduledOrderCount();
        logger.info("Timed tasks Init end...{}", DateUtil.getCurrentDate());
    }

    /**
     * 初始化交易类型
     */
    private void initTradeStatus() {
        for (TradeStatusEnum status : TradeStatusEnum.values()) {
            if (status.getCode() != 0) {
                TRADE_STATUS_RESULT.add(new TradeStatusDto(status.getCode(), status.getValue()));
            }
        }
    }

    private void initScheduledOrderCount() {
        logger.info("initScheduledOrderCount tasks open:{}", DateUtil.getCurrentDate());
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                logger.info("run initScheduledOrderCount:{}", DateUtil.getCurrentDate());
                for (OrderTypeEnum type : OrderTypeEnum.values()) {
                    Contants.ORDER_COUNT_MAP.put(type.getValue(), 0);
                }
                OrderExample example = new OrderExample();
                example.getOredCriteria().add(example.createCriteria().andTypeEqualTo(OrderTypeEnum.WAITING.getCode()));
                orderService.countByExample(example);
            }
        };
        logger.info("initScheduledOrderCount tasks end:{}", DateUtil.getCurrentDate());
        service.scheduleAtFixedRate(runnable, 1, 60, TimeUnit.SECONDS);
    }

    /**
     * 初始化游戏可接受数量
     */
    private void initScheduledGameCount() {
        logger.info("initScheduledGameCount tasks open:{}", DateUtil.getCurrentDate());
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                logger.info("run initScheduledGameCount:{}", DateUtil.getCurrentDate());
                Result<List<Game>> result = gameService.selectByExample(null);
                //初始化 游戏未接受计数器
                for (Game game : result.getData()) {
                    Contants.GAME_COUNT_MAP.put(game.getId(), 0);
                }
                //初始化 订单类型计数器
                for (OrderTypeEnum type : OrderTypeEnum.values()) {
                    Contants.ORDER_COUNT_MAP.put(type.getValue(), 0);
                }
                OrderExample example = new OrderExample();
                example.getOredCriteria().add(example.createCriteria().andTypeEqualTo(OrderTypeEnum.WAITING.getCode()));
                orderService.countByExample(example);
                Contants.GAME_RESULT.getData().clear();
                gameService.selectByExample(null);
            }
        };
        logger.info("initScheduledGameCount tasks end:{}", DateUtil.getCurrentDate());
        service.scheduleAtFixedRate(runnable, 1, 60 * 60 * 12, TimeUnit.SECONDS);
    }

    /**
     * 设置订单为过期
     */
    private void initScheduledExpired() {
        logger.info("initScheduledExpired tasks open:{}", DateUtil.getCurrentDate());
        Runnable runnable = new Runnable() {
            public void run() {
                try {
                    logger.info("run initScheduledExpired:{}", DateUtil.getCurrentDate());
//                        orderService.setExpired();
                    tradeService.setExpiredFromEmail();
                } catch (Exception e) {
                    logger.info("initScheduledExpired tasks Exception:{}", e);
                }
            }
        };
        logger.info("initScheduledExpired tasks end:{}", DateUtil.getCurrentDate());
        // 第二个参数为首次执行的延时时间，第三个参数为定时执行的间隔时间
        service.scheduleAtFixedRate(runnable, 1, 3, TimeUnit.HOURS);
    }

    /**
     * 设置数据库备份
     */
    private void initScheduledExecutorService() {
        logger.info("initScheduledExecutorService tasks open:{}", DateUtil.getCurrentDate());
        Runnable runnable = new Runnable() {
            public void run() {
                try {
                    logger.info("run initScheduledExecutorService:{}", DateUtil.getCurrentDate());
                    //清楚缓存
                    List<Game> list = Contants.GAME_RESULT.getData();
                    if (CollectionUtils.isNotEmpty(list)) {
                        list.clear();
                    }
                    logger.info("DB backUp start...");
                    //数据库备份
                    boolean bool = MySQLDatabaseBackup.exportDatabaseTool(
                            PropertiesUtil.getProperty("hostIP"), PropertiesUtil.getProperty("jdbc.username"),
                            PropertiesUtil.getProperty("jdbc.password"), PropertiesUtil.getProperty("savePath"),
                            PropertiesUtil.getProperty("fileName") + DateUtil.getCurrentDateShort() + ".sql",
                            PropertiesUtil.getProperty("databaseName"));
                    logger.info("DB backUp result:{}", bool);
                } catch (Exception e) {
                    logger.info("initScheduledExecutorService tasks Exception:{}", e);
                }
            }
        };
        // 第二个参数为首次执行的延时时间，第三个参数为定时执行的间隔时间
        service.scheduleAtFixedRate(runnable, Contants.HOUR, Contants.HOUR, TimeUnit.HOURS);
    }
}
